package Concurrency1.Chapter01_Base;

import java.util.ArrayList;
import java.util.List;

/**
 * 功能说明： 并发编程中的数据原子性问题
 * 1, 是什么?
 * 多线程操作共享数据, 数据被覆盖
 * 2, 场景?
 * 多线程对共享变量做自加操作, 由于自加操作不是原子性的(本质是一个复合操作),多线程共同执行时, 导致赋值被覆盖
 * 3, 解决办法:
 * 让非原子的操作, 由并行执行, 变为串行执行
 * 开发人员：@author MaLi
 */
public class C05_Atomicity {
    private volatile static int num = 0; //volatile修饰了变量, 对多线程都是可见的.
    private final static Object lock = new Object();
    public static void main(String[] args) {
        List<Thread> threads = new ArrayList<>();
        int one_million = 10000;
        //1,创建10个线程
        for (int i = 0; i < 10; i++) {
            //创建10个线程
            threads.add(new Thread(() -> {
                //线程任务: 进行1万次自加1
                for (int j = 0; j < one_million; j++) {
                    //不加锁, 多线程并行执行
//                    ++num;
                    //加锁, 多线程串行执行
                    synchronized (lock) {
                        ++num;
                    }
                }
            }, "Thread" + i));
        }

        //开启所有线程
        for (Thread thread : threads) {
            thread.start();
        }
        //Main线程等待所有线程执行完成
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.err.println("理论结果: 100000");
        System.out.println("实际结果: " + num);
    }
}
